package com.srdl.synchronizedTest;

import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class SynchronizedByKey {

    Map<String, ReentrantLock> muteCache = new ConcurrentHashMap<>();

    public void exec(String key,Runnable statement){
        ReentrantLock mutex4Key = null;
        ReentrantLock mutexInCache;
        do {
            if (mutex4Key != null){
                mutex4Key.unlock();
            }
            mutex4Key = muteCache.computeIfAbsent(key, k -> new ReentrantLock());
            mutex4Key.lock();
            mutexInCache = muteCache.get(key);
        } while (mutexInCache == null || mutex4Key != mutexInCache);

        try {
            statement.run();
        }catch (Exception e){

        }finally {
            if (mutex4Key.getQueueLength() == 0){
                muteCache.remove(key);
            }
            mutex4Key.unlock();
        }
    }

}
